package com.wanxi.coupons.service.impl;

import com.alibaba.fastjson.JSON;
import com.wanxi.coupon.api.entity.Coupon;
import com.wanxi.coupon.api.entity.CouponEnterprise;
import com.wanxi.coupon.api.entity.CouponSku;
import com.wanxi.coupon.api.entity.CouponStatistic;
import com.wanxi.coupon.api.feign.CouponFeignClient;
import com.wanxi.coupon.api.query.*;
import com.wanxi.coupon.api.result.CommonResult;
import com.wanxi.coupon.api.vo.*;
import com.wanxi.coupons.mapper.CouponAdminMapper;
import com.wanxi.coupons.mapper.CouponEnterpriseMapper;
import com.wanxi.coupons.mapper.CouponUserMapper;
import com.wanxi.coupons.service.util.EntityCreateUtil;
import com.wanxi.coupons.service.util.Verify;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName: CouponAdminServiceImpl
 * @Description: 优惠券服务层
 * @Author lxl
 * @Date 2021/12/30
 * @Version 1.0
 */
@Api(tags = "优惠券接口")
@RestController
public class CouponServiceImpl implements CouponFeignClient {

    //    日志
    private static Logger log = LoggerFactory.getLogger(CouponServiceImpl.class);

    //    注入admin的mapper
    @Autowired
    private CouponAdminMapper adminMapper;
    // 注入商家的mapper
    @Autowired
    private CouponEnterpriseMapper enterpriseMapper;
    //    注入用户mapper
    @Autowired
    private CouponUserMapper userMapper;

    //    注入工具类
    @Autowired
    private EntityCreateUtil entityCreateUtil;
    //    校验
    @Resource
    private Verify verify;


    /**
     * @return CommonResult
     * @Author lsp
     * @Description //TODO findAll 通过给定条件查询所有条数
     * @Date 2021/12/31 10:40
     * @Params * @param couponAdminQuery
     **/
    @ApiOperation("平台查询优惠券的信息")
    @GetMapping("admin/findAll")
    @Override
    public CommonResult adminFindAll(CouponAdminQuery couponAdminQuery) {
        String massage = "";
        try {
//            转成entity实体
            Coupon adminCoupon = entityCreateUtil.adminQueryTdoTransitionEntity(couponAdminQuery);
//            去数据库查询
            List<Coupon> all = adminMapper.findAll(adminCoupon);
//            转换Vo
            List<CouponAdminVo> list = entityCreateUtil.entityTransitionAdminVo(all);
            return CommonResult.success(adminMapper.getCount(adminCoupon), list);
        } catch (Exception e) {
            massage = e.getMessage();
            log.info(massage);
        }
        return CommonResult.failed(massage);
    }

    /**
     * @return CommonResult
     * @Author lxl
     * @Description //TODO findStatistic 根据给定参数查询对应的优惠券统计信息
     * @Date 2021/12/31 10:55
     * @Params * @param couponAdminStatisticQuery
     **/
    @ApiOperation("平台查询优惠券的统计信息")
    @GetMapping("admin/findStatistic")
    @Override
    public CommonResult adminFindStatistic(CouponAdminStatisticQuery couponAdminStatisticQuery) {
        String message = "";
        try {
            Coupon coupon = entityCreateUtil.adminStatisticTransitionEntity(couponAdminStatisticQuery);
            List<CouponStatistic> statistic = adminMapper.findStatistic(coupon);

            return CommonResult.success(statistic.size(), entityCreateUtil.adminEntityTransitionStatistic(statistic));
        } catch (Exception e) {
            message = e.getMessage();
        }

        return CommonResult.failed(message);
    }


    /**
     * @return CommonResult
     * @Author lxl
     * @Description //TODO findById 通过id查询优惠券信息
     * @Date 2021/12/31 10:56
     * @Params * @param id
     **/
    @ApiOperation("平台通过id查询优惠券")
    @ApiImplicitParam(name = "id", value = "要查询的优惠券id", dataType = "Integer")
    @GetMapping("admin/findById")
    @Override
    public CommonResult adminFindById(Long id) {
        String message = "";
        try {
            List byId = adminMapper.findById(id);
            return CommonResult.success(entityCreateUtil.entityTransitionAdminVo(byId));
        } catch (Exception e) {
            message = e.getMessage();
            log.info(message);
        }
        return CommonResult.failed(message);
    }

    /**
     * @return CommonResult
     * @Author lxl
     * @Description //TODO   添加优惠券信息
     * @Date 2021/12/31 10:57
     * @Params * @param couponAdminTDO
     **/
    @Transactional
    @ApiOperation("平台添加优惠券数据接口")
    @PostMapping("admin/add")
    @Override
    public CommonResult adminAdd(CouponAdminTDO couponAdminTDO) {
        String message = "";
        try {
//                校验
            boolean b = verify.admin(couponAdminTDO);
            if (couponAdminTDO.getDiscount() != null) {
                if (couponAdminTDO.getFullReduction() != null || couponAdminTDO.getCouponMoney() != null) {
                    return CommonResult.failed("优惠金额设置错误");
                }
            }
            if ((couponAdminTDO.getFullReduction() != null && couponAdminTDO.getCouponMoney() != null) && couponAdminTDO.getDiscount() != null) {
                return CommonResult.failed("优惠金额设置错误");
            }
            if ((couponAdminTDO.getFullReduction() != null && couponAdminTDO.getCouponMoney() == null) ||
                    (couponAdminTDO.getFullReduction() == null && couponAdminTDO.getCouponMoney() != null)) {
                return CommonResult.failed("优惠金额设置错误");
            }
//          取出范围集合
            List<CouponEnterprise> enterpriseRange = couponAdminTDO.getEnterpriseRange();


            //        将入参CouponAdminTDO复制到Coupon 方便与数据库交互
            Coupon coupon = entityCreateUtil.adminTdoTransitionEntity(couponAdminTDO);
            //      数据库优惠券表添加
            int add = adminMapper.add(coupon);

            //       管理员优惠券表添加
            int addAdminCoupon = addAdminCoupon(coupon);

            //        优惠券商家关联表添加
            //        设置优惠券id
            enterpriseRange.forEach(a -> a.setCouponId(coupon.getId()));
            int enterpriseCoupon = addEnterpriseCoupon(enterpriseRange);

//          t统计表添加
            int statistic = adminMapper.addStatistic(coupon.getId());
            coupon.setPastTime(couponAdminTDO.getPastTime());
            int i = adminMapper.updatePast(coupon);
            return CommonResult.success(add + addAdminCoupon + enterpriseCoupon + statistic);

        } catch (Exception e) {
            message = e.getMessage();
            log.info(message);

        }

        return CommonResult.failed("添加优惠券错误，错误信息：" + message);
    }

    /**
     * @return CommonResult
     * @Author lxl
     * @Description //TODO 删除优惠券信息
     * @Date 2021/12/31 11:00
     * @Params * @param id
     **/
    @Transactional
    @ApiOperation("平台删除优惠券数据接口")
    @ApiImplicitParam(name = "id", value = "要删除的优惠券的id，", dataType = "Integer")
    @PutMapping("admin/delete")
    @Override
    public CommonResult adminDelete(Integer id) {
        String message = "";
        try {
            int delete = adminMapper.delete(id);
            return CommonResult.success(delete);
        } catch (Exception e) {
            message = e.getMessage();
            log.info(message);
        }
        return CommonResult.failed("删除错误：" + message);
    }

    /**
     * @return CommonResult
     * @Author lxl
     * @Description //TODO 查询给定条件的优惠券条数
     * @Date 2021/12/31 11:00
     * @Params * @param couponAdminQuery
     **/
    @ApiOperation("查询优惠券的条数")
    @GetMapping("admin/getCount")
    @Override
    public CommonResult adminGetCount(CouponAdminQuery couponAdminQuery) {

        try {
            Coupon adminCoupon = entityCreateUtil.adminQueryTdoTransitionEntity(couponAdminQuery);
            int count = adminMapper.getCount(adminCoupon);
            return CommonResult.success(count);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return CommonResult.failed();
    }


    /**
     * @Author lxl
     * @Description //TODO 管理员优惠券关系表字段添加
     * @Date 2021/12/31 12:05
     * @Params * @param coupon
     **/

    private int addAdminCoupon(Coupon coupon) {
        return adminMapper.addAdminCoupon(coupon);
    }

    /**
     * @Author lxl
     * @Description //TODO 商品优惠券关系表添加
     * @Date 2021/12/31 12:06
     * @Params * @param list
     **/

    private int addEnterpriseCoupon(List<CouponEnterprise> list) {
        return adminMapper.addEnterpriseCoupon(list);
    }


    /**
     * @return CommonResult
     * @Author lxl
     * @Description //TODO findAll 根据条件查询所有满足条件的优惠券
     * @Date 2021/12/31 9:23
     * @Params * @param couponEnterpriseQuery
     **/
    @ApiOperation("查询优惠券的所有信息")
    @GetMapping("enterprise/findAll")
    @Override
    public CommonResult enterpriseFindAll(CouponEnterpriseQuery couponEnterpriseQuery) {

        String message = "";

        if (couponEnterpriseQuery.getEnterpriseId() == null) {
            return CommonResult.failed("商家id不能为空");
        }
        try {
//           去数据库查询
            CommonQuery clone = (CommonQuery) couponEnterpriseQuery.clone();
            List<Coupon> all = enterpriseMapper.findAll(clone);
//            转化为返回前端的实体
            List<CouponEnterpriseVo> data = entityCreateUtil.entityTransitionEnterprisVo(all);
            return CommonResult.success(data.size(), data);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("查询失败");
            message = e.getMessage();
        }
        return CommonResult.failed("查询失败：" + message);
    }

    /**
     * @return CommonResult
     * @Author lxl
     * @Description //TODO findStatistic 查询满足条件的优惠券统计信息
     * @Date 2021/12/30 9:24
     * @Params * @param couponEnterpriseStatisticQuery
     **/
    @ApiOperation("商家查询优惠券的统计信息")
    @GetMapping("enterprise/findStatistic")
    @Override
    public CommonResult enterpriseFindStatistic(CouponEnterpriseStatisticQuery couponEnterpriseStatisticQuery) {
        String message = "";
        if (couponEnterpriseStatisticQuery.getEnterpriseId() == null) {
            log.info("商家id不能为空");
            return CommonResult.failed("商家id不能为空");
        }
        try {
            CommonQuery clone = (CommonQuery) couponEnterpriseStatisticQuery.clone();
            List<CouponStatistic> statistic = enterpriseMapper.findStatistic(clone);
            return CommonResult.success(statistic.size(), statistic);
        } catch (Exception e) {
            message = e.getMessage();
            log.info("查询统计错误：" + message);
        }

        return CommonResult.failed(message);
    }

    /**
     * @return CommonResult
     * @Author lxl
     * @Description //TODO findById 通过id查询商家的优惠券信息
     * @Date 2021/12/30 9:25
     * @Params * @param id
     **/
    @ApiOperation("通过id查询优惠券")
    @ApiImplicitParam(name = "id", value = "要查询的优惠券id", dataType = "Integer")
    @GetMapping("enterprise/findById")
    @Override
    public CommonResult enterpriseFindById(Long id) {

        String message = "";
        try {
            List byId = enterpriseMapper.findById(id);
//           封装返回前端的vo
            List list = entityCreateUtil.entityTransitionAdminVo(byId);
            return CommonResult.success(list.size(), list);
        } catch (Exception e) {
            e.printStackTrace();
            message = e.getMessage();
        }
        return CommonResult.failed(message);
    }

    /**
     * @return CommonResult
     * @Author lxl
     * @Description //TODO add 商家添加优惠券信息
     * @Date 2021/12/30 9:26
     * @Params * @param couponEnterpriseTDO
     **/
    @Transactional
    @ApiOperation("商家添加优惠券数据接口")
    @PostMapping("enterprise/add")
    @Override
    public CommonResult enterpriseAdd(CouponEnterpriseTDO couponEnterpriseTDO) {

        String message = "";
        synchronized (CouponServiceImpl.class) {
            try {
                boolean b = verify.enterprise(couponEnterpriseTDO);
                if (couponEnterpriseTDO.getDiscount() != null) {
                    if (couponEnterpriseTDO.getFullReduction() != null || couponEnterpriseTDO.getCouponMoney() != null) {
                        return CommonResult.failed("优惠金额设置错误");
                    }
                }

                if ((couponEnterpriseTDO.getFullReduction() != null && couponEnterpriseTDO.getCouponMoney() != null) && couponEnterpriseTDO.getDiscount() != null) {
                    return CommonResult.failed("优惠金额设置错误");
                }
                if ((couponEnterpriseTDO.getFullReduction() != null && couponEnterpriseTDO.getCouponMoney() == null) ||
                        (couponEnterpriseTDO.getFullReduction() == null && couponEnterpriseTDO.getCouponMoney() != null)) {
                    return CommonResult.failed("优惠金额设置错误");
                }
                Coupon coupon = entityCreateUtil.enterpriseVoTransitionEntity(couponEnterpriseTDO);

//            优惠券表添加
                int couponAdd = enterpriseMapper.add(coupon);
//             商家优惠券关系表添加
                CouponEnterprise couponEnterprise = CouponEnterprise.builder()
                        .enterpriseId(coupon.getEnterpriseId())
                        .couponId(coupon.getId()).build();
                int enterpriseCouponAdd = enterpriseMapper.addEnterpriseCoupon(couponEnterprise);

//            商品优惠券关系表添加
//            取出多个商品集合
                List<CouponSku> skuRange = couponEnterpriseTDO.getSkuRange();
                skuRange.forEach(a -> a.setCouponId(coupon.getId()));
                int skuAdd = enterpriseMapper.addSkuCoupon(skuRange);
//             统计表添加
                int statistic = enterpriseMapper.addStatistic(coupon.getId());
                coupon.setPastTime(couponEnterpriseTDO.getPastTime());
//                修改过期状态
                int i = adminMapper.updatePast(coupon);
                return CommonResult.success(couponAdd + enterpriseCouponAdd + skuAdd + statistic, "成功");
            } catch (Exception e) {
                e.printStackTrace();
                message = e.getMessage();
            }

        }

        return CommonResult.failed("添加失败：" + message);
    }

    /**
     * @return CommonResult
     * @Author lxl
     * @Description //TODO delete 通过id删除优惠券信息
     * @Date 2021/12/30 9:26
     * @Params * @param id
     **/
    @Transactional
    @ApiOperation("商家删除优惠券数据接口")
    @ApiImplicitParam(name = "id", value = "要删除的优惠券的id，", dataType = "Integer")
    @PutMapping("enterprise/delete")
    @Override
    public CommonResult enterpriseDelete(Integer id) {

        String message = "";
        try {
            int delete = enterpriseMapper.delete(id);
            return CommonResult.success(delete, "成功");
        } catch (Exception e) {
            e.printStackTrace();
            message = e.getMessage();
        }
        return CommonResult.failed("删除失败：" + message);
    }


    /**
     * @return CommonResult
     * @Author lxl
     * @Description //TODO getCount 查询优惠券条数
     * @Date 2021/12/30  9:27
     * @Params * @param couponEnterpriseQuery
     **/
    @ApiOperation("商家查询优惠券的条数")
    @GetMapping("enterprise/getCount")
    @Override
    public CommonResult enterpriseGetCount(CouponEnterpriseQuery couponEnterpriseQuery) {
        String massage = "";
        try {
            CommonQuery clone = (CommonQuery) couponEnterpriseQuery.clone();
            int count = enterpriseMapper.getCount(clone);
            return CommonResult.success(count);
        } catch (Exception e) {
            massage = e.getMessage();
        }

        return CommonResult.failed(massage);
    }


    @ApiOperation("用户查询优惠券的信息")
    @GetMapping("user/findAll")
    @Override
    public CommonResult<List<CouponUserVo>> userFindAll(CouponUserQuery coupon) {
        String message = "";

        if (coupon.getUserId() == null) {
            return CommonResult.failed("用户id不能为空");
        }

        try {
            Coupon userCoupon = entityCreateUtil.userQueryTransitionCoupon(coupon);
            List<Coupon> all = userMapper.findAll(userCoupon);
            List<CouponUserVo> list = entityCreateUtil.userCouponVoTransitionEntity(all);
            return CommonResult.success(list.size(), list);
        } catch (Exception e) {
            message = e.getMessage();
        }

        return CommonResult.failed(message);
    }

    @ApiOperation("通过id查询用户的优惠券")
    @ApiImplicitParam(name = "id", value = "要查询的优惠券id", dataType = "Integer")
    @GetMapping("user/findById")
    @Override
    public CommonResult<List<CouponUserVo>> userFindById(Long id) {
        String message = "";
        try {
            List<Coupon> byId = userMapper.findById(id);
            List<CouponUserVo> list = entityCreateUtil.userCouponVoTransitionEntity(byId);
            return CommonResult.success(list.size(), list);
        } catch (Exception e) {
            message = e.getMessage();
        }
        return CommonResult.failed(message);
    }

    @Transactional //开启事务处理
    @ApiOperation("用户优惠券领取接口")
    @PostMapping("user/add")
    @Override
    public CommonResult userAdd(CouponUserTDO coupon) {

        if (coupon.getCouponId() == null) {
            log.info("优惠券id不能为空");
            return CommonResult.failed("优惠券id不能为空");
        }
        String message = "";
        synchronized (CouponServiceImpl.class) {
            try {
                // 实体转换
                Coupon userCoupon = entityCreateUtil.userTDOTransitionCoupon(coupon);
//            去查询优惠券是否可领取
                CouponStatistic isGet = userMapper.findIsGet(coupon.getCouponId());
                if (isGet.getQuota() == null) {
                    log.info("没有该优惠券信息");
                    return CommonResult.failed("没有该优惠券信息");
                }
                int res = isGet.getQuota() - isGet.getGetNumber();
                if (res == 0) {
                    log.info("优惠券领取完了");
                    return CommonResult.failed("优惠券领取完了");
                }
                // 添加用户优惠券信息
                int add = userMapper.add(userCoupon);

                if (add == 0) {
                    return CommonResult.failed("用户已领取过啦！！");
                }
                //            更新统计信息
                isGet.setGetNumber(isGet.getGetNumber() + 1);
                int statistic = userMapper.addCouponStatistic(isGet);

                return CommonResult.success(add + statistic);
            } catch (Exception e) {
                message = e.getMessage();
                log.info(message);
            }
            return CommonResult.failed(message);
        }
    }

    @Transactional
    @ApiOperation("用户优惠券使用接口")
    @PostMapping("user/useCoupon")
    @Override
    public CommonResult useCoupon(CouponUserTDO couponUserTDO) {
        String message = "";
        try {
//            转换类型
            Coupon coupon = Coupon.builder()
                    .userId(couponUserTDO.getUserId())
                    .couponId(couponUserTDO.getCouponId()).build();
//          查询是否可使用
            List<Coupon> all = userMapper.findUsable(coupon);
            if (!all.isEmpty()) {
                if (all.get(0).getUserCouponStatus() == 2 || all.get(0).getUserCouponStatus() == 0) {
                    return CommonResult.failed("不可使用优惠券");
                }
                int i = userMapper.useCoupon(coupon);

                CouponStatistic isGet = userMapper.findIsGet(coupon.getCouponId());
                isGet.setUseNumber(isGet.getUseNumber() + 1);
                userMapper.addCouponStatistic(isGet);
                return CommonResult.success(i);
            }

        } catch (Exception e) {
            message = e.getMessage();
            log.info(message);
        }
        return CommonResult.failed(message);
    }

    @Override
    public CommonResult findIsUse(CouponIsUseQuery query) {
        Coupon build = Coupon.builder()
                .userId(query.getUserId())
                .couponId(query.getCouponId())
                .build();
        List<Coupon> isUse = userMapper.findIsUse(build);
        if (isUse.isEmpty()) {
            return CommonResult.failed("优惠券不可用");
        }

        String useRange = isUse.get(0).getUseRange();
        List<Coupon> parse = (List<Coupon>) JSON.parse(useRange);
//        是否通用
        if (parse.get(0).getSkuId() == 0) {
            return CommonResult.success("可用");
        }
        if (parse.get(0).getSkuId() == null && parse.get(0).getEnterpriseId() == 0) {
            return CommonResult.success("可用");
        }
        if (parse.get(0).getSkuId() != null && parse.get(0).getSkuId() != 0) {
            parse.stream().filter(a -> a.getSkuId().equals(query.getSkuId())).forEach(b -> System.out.println(b.toString()));
            return CommonResult.success(parse);
        }

        if (parse.get(0).getEnterpriseId() == 0 && parse.get(0).getSkuId() == null) {
            return CommonResult.success("可用");
        }
        if (parse.get(0).getEnterpriseId() != null && parse.get(0).getEnterpriseId() != 0) {
            parse.stream().filter(a -> a.getEnterpriseId().equals(query.getEnterpriseId())).forEach(b -> System.out.println(b.toString()));
            return CommonResult.success(parse);
        }

        System.out.println(parse.toString());
        return null;
    }

}
